package com.hp.provider.rabbit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.ReturnedMessage;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.core.RabbitTemplate.ConfirmCallback;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

/**
 * 发送消息服务
 *
 * @author <a href="mailto:xing.dong@sha.ontime-express.com">Xavier Dong</a>
 * @date
 */
@Component
public class MessageServiceImpl implements IMessageService, ConfirmCallback, RabbitTemplate.ReturnsCallback {

    private static Logger log = LoggerFactory.getLogger(MessageServiceImpl.class);

    @Resource
    private RabbitTemplate rabbitTemplate;

    @Override
    public void sendMessage(String exchange, String routingKey, Object msg) {
        //消息发送失败返回到队列中, yml需要配置 publisher-returns: true
        // 触发setReturnCallback回调必须设置mandatory=true,否则Exchange没有找到Queue就会丢弃掉消息,而不会触发回调
        rabbitTemplate.setMandatory(true);
        //消息消费者确认收到消息后，手动ack回执
        rabbitTemplate.setConfirmCallback(this);
        // 消息是否从Exchange路由到Queue,注意:这是一个失败回调,只有消息从Exchange路由到Queue失败才会回调这个方法
        rabbitTemplate.setReturnsCallback(this);
        //发送消息
        rabbitTemplate.convertAndSend(exchange, routingKey, msg);
    }

    /**
     * 消息是否从Exchange路由到Queue,注意:这是一个失败回调,只有消息从Exchange路由到Queue失败才会回调这个方法
     *
     * @param returned 返回
     */
    @Override
    public void returnedMessage(ReturnedMessage returned) {
        log.info("---- returnedMessage ----replyCode=" + returned.getReplyCode() + " replyText=" + returned.getReplyText() + " ");
    }

    /**
     * 消息是否成功发送到Exchange
     *
     * @param correlationData 关联数据
     * @param ack             消
     * @param cause           导致
     */
    @Override
    public void confirm(CorrelationData correlationData, boolean ack, String cause) {
        log.info("---- confirm ----ack=" + ack + "  cause=" + String.valueOf(cause));
        if (ack) {
            log.info("消息成功发送到Exchange");
            log.info("---- confirm ----ack==true  cause=" + cause);
            String msgId = correlationData.getId();
        } else {
            log.info("---- confirm ----ack==false  cause=" + cause);
            log.info("消息发送到Exchange失败,{},cause:{}", correlationData, cause);
        }

    }

}